﻿using Inovout.Repositories;
using Inovout.Security;
using Inovout.Services;
using NHibernate.Criterion;
using NHibernate.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Inovout.Security.Services
{
    public class FormsUserCredentialService : RepositoryService<FormsUserCredential>, IFormsUserCredentialService, IFormsAuthenticationService
    {
        public bool Authenticate(string userName, string password)
        {
            FormsUserCredential formsUserCredential = new FormsUserCredential();
            //根据用户名查找用户是否存在
             formsUserCredential = base.Repository.Find(Restrictions.Eq("UserName", userName).IgnoreCase());
            if (formsUserCredential != null)
            {
                return formsUserCredential.Password.Equals(Encrypt(password, formsUserCredential.PasswordSalt));
            }

            //根据电子邮件查找用户是否存在
             formsUserCredential = ComponentRegistry.Resolve<IRepository<FormsUserCredential>>().Find(Restrictions.And(Restrictions.Eq("Provider", "Inovout"), Restrictions.Eq("Email", userName)));
             if (formsUserCredential != null)
            {
                return formsUserCredential.Password.Equals(Encrypt(password, formsUserCredential.PasswordSalt));
            }
            return false;
        }


        public FormsUserCredential FindByName(string Name)
        {
            return base.Repository.Find(Restrictions.Eq("UserName", Name).IgnoreCase());
        }

        public FormsUserCredential FindByEmail(string email)
        {
            return ComponentRegistry.Resolve<IRepository<FormsUserCredential>>().Find(Restrictions.And(Restrictions.Eq("Provider", "Inovout"), Restrictions.Eq("Email", email)));
        }

        public FormsUserCredential FindByUserNameOrEmail(string name)
        {
            FormsUserCredential formsUserCredential = new FormsUserCredential();
            //根据用户名查找用户是否存在
            formsUserCredential = base.Repository.Find(Restrictions.Eq("UserName", name).IgnoreCase());
            if (formsUserCredential != null)
            {
                return formsUserCredential;
            }

            //根据电子邮件查找用户是否存在
            formsUserCredential = ComponentRegistry.Resolve<IRepository<FormsUserCredential>>().Find(Restrictions.And(Restrictions.Eq("Provider", "Inovout"), Restrictions.Eq("Email", name)));
            if (formsUserCredential != null)
            {
                return formsUserCredential;
            }
            return null;
        }

        public override void Save(FormsUserCredential entity)
        {
            if (string.IsNullOrEmpty(entity.PasswordSalt))
            {
                entity.PasswordSalt = GenerateSalt();
            }
            entity.Password = Encrypt(entity.Password, entity.PasswordSalt);
            base.Save(entity);
        }
       
        private string Encrypt(string password, string salt)
        {
            HMACMD5 hmacmd5 = new HMACMD5(Convert.FromBase64String(salt));
            return Convert.ToBase64String(hmacmd5.ComputeHash(Encoding.Unicode.GetBytes(password)));
        }
        private string GenerateSalt()
        {
            byte[] buffer = new byte[0x10];
            new RNGCryptoServiceProvider().GetBytes(buffer);
            return Convert.ToBase64String(buffer);
        }

    }
}
